//! osnovne funkcije za ispis na zaslon ("konzolu")

#include "ispis.h"
#include "razno.h"

//! ispis na "konzolu" od trenutne pozicije
int j_ispisi (const char *format, ...)
{
	char **arg = (char **) &format;
	int c;
	char buf[20];
	
	arg++; //dohvacam prvi argument iza 'format'a (sve je na stogu!)

	while ((c = *format++) != 0) {
		if (c != '%') {
			j_ispisi_znak(c);
		}
		else {
			char *p;
			
			c = *format++;
			switch (c) {
				case 'd':
				case 'u':
				case 'x':
				case 'X':
					j_itoa(buf, c, *((int *) arg++));
					p = buf;
					while (*p)
						j_ispisi_znak(*p++);
					break;
					
				case 's':
					p = *arg++;
					if (!p)
						p = "(null)";
					while (*p)
						j_ispisi_znak(*p++);
					break;
					
				default: /* pretpostavka je da je to 'c' */
					j_ispisi_znak(*((int *) arg++));
					break;
			}
		}
	}

	return 0;
}

/* Pretvori broj 'd' niz znakova u 'buf' pretpostavljajuci dekadsku ili 
   heksadekadsku bazu (base = 'd'/'u'/'x'/'X').
 */
void j_itoa (char *buf, int base, int d)
{
	char *p = buf;
	char *p1, *p2, firsthexchar;
	unsigned long ud = d;
	int divisor = 10;
	int digits = 0;
	
	/* ako je %d a d je manji od nule, stavi `-' na pocetak */
	if (base == 'd' && d < 0) {
		*p++ = '-';
		buf++;
		ud = -d;
	} else if (base == 'x' || base == 'X') {
		divisor = 16;
	}
	
	firsthexchar = (base == 'x' ? 'a' : 'A');

	/* dijeli 'ud' sa bazom 'divisor' dok 'ud' ne postane 0 */
	do {
		int remainder = ud % divisor;
		
		*p++ = (remainder < 10) ? remainder + '0' :
						remainder + firsthexchar - 10;
		digits++;
	} while (ud /= divisor);
	
	//dodaj vodece nule za heksa prikaz
	if (base == 'x' || base == 'X') {
		while (digits < 8) {
			digits++;
			*p++ = '0';
		}
		*p++ = 'x';
		*p++ = '0';
	} 
	/* Terminairajuci znak na kraj */
	*p = 0;
	
	/* Okreni niz */
	p1 = buf;
	p2 = p - 1;
	while (p1 < p2) {
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2--;
	}
}
